package com.shujia

import scala.io.Source

object Code35ClassTop10RowNumber {
  def main(args: Array[String]): Unit = {
    val stuInfoList: List[(String, String, Int, String, String)] = Source
      .fromFile("scala_code/data/students.txt")
      .getLines()
      // 将读取到的每一行数据转换成List中的元素
      .toList
      .map(
        (line: String) => {
          val colum: Array[String] = line.split(",")
          // (id,name,age,gender,clazz)
          //  Tuple相比较Array 其元素的数据类型可以多样
          (colum(0), colum(1), colum(2).toInt, colum(3), colum(4))
        }
      )


    val stuTotalScore: Map[String, Int] = Source
      .fromFile("scala_code/data/score.txt")
      .getLines()
      // 将读取到的每一行数据转换成List中的元素
      .toList
      .map(
        line => {
          val column: Array[String] = line.split(",")
          // (id,(科目ID,成绩))
          (column(0), column(1), column(2))
        }
      )
      .groupBy(
        oneScore => oneScore._1
      )
      .map(
        keyValue => {
          val stuID: String = keyValue._1
          val oneStuScore: List[(String, String, String)] = keyValue._2

          // 求一个学生的总分： 先取出成绩，再求和
          // 方式一：
          //          val total_score: Int = oneStuScore
          //            // _ 代表一个成绩
          //            .map(_._3.toInt)
          //            // sum要求是一个int类型
          //            .sum

          // 方式二：
          var total_score: Int = 0
          oneStuScore.foreach(
            oneScore => total_score += oneScore._3.toInt
          )
          // 返回一个学生ID和其总分
          (stuID, total_score)
        }
      )

    val stuJoinScoreRes: List[(String, String, Int, String, String, Int)] = stuInfoList
      .map(
        oneInfo => {
          if (stuTotalScore.contains(oneInfo._1)) {
            val total: Int = stuTotalScore(oneInfo._1)
            (oneInfo._1, oneInfo._2, oneInfo._3, oneInfo._4, oneInfo._5, total)
          } else {
            (oneInfo._1, oneInfo._2, oneInfo._3, oneInfo._4, oneInfo._5, 0)
          }
        }
      )

    // stuJoinScoreRes 是关联后的结果 包含学生基本信息和总分数据
    stuJoinScoreRes
      // 班级前10
      // 对班级进行分组
      .groupBy(_._5)
      //      .map(

      .flatMap(
        // 对每个相同班级中的所有数据进行处理
        keyValue => {
          val clazz: String = keyValue._1
          val oneClazzAllStu: List[(String, String, Int, String, String, Int)] = keyValue._2
          // 对分数进行排名：1.根据总分进行排序 2.再遍历每个数据，拼接一个累加的名次
          var rowNumber: Int = 0

          oneClazzAllStu
            .sortBy(
              // 根据成绩倒序排序
              oneStu => -oneStu._6
            )
            .map(
              oneStu => {
                rowNumber += 1
                // 匿名函数最后一行为默认返回值
                (oneStu._1, oneStu._2, oneStu._3, oneStu._4, oneStu._5, oneStu._6, rowNumber)
//                rowNumber += 1
              }
            )
          // 该方式效率更高
//            .take(10)
          //          clazzTop10
        }
      )
      .filter(
        _._7 <= 10
      )
      //      .flatMap(
      //        _._2
      //      )
      .foreach(println)

    // 作业：如何实现Rank和DenseRank

  }
}
